/*
 * Copyright (c) 2014-2015 Luca Agostini, Alessandro Cantini, Alessandro Dignani
 *
 * This file is part of MeteoCal.
 *
 * MeteoCal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.polimi.se2.agostini_cantini_dignani.meteocal.business;

import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.Event;
import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.Notification;
import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.User;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import static org.junit.Assert.*;

@RunWith(Arquillian.class)
public class NotificationManagerIT {

	private static final String DESCRIPTION = "notification description";

	private Event event;
	private User user;

	@EJB
	private UserManager um;

	@EJB
	private NotificationManager cut;

	@EJB
	private EventManager eventMgr;

	@PersistenceContext
	private EntityManager em;

	@Deployment
	public static WebArchive createArchiveAndDeploy() {
		return ShrinkWrap.create(WebArchive.class)
				.addPackages(false, Notification.class.getPackage(), NotificationManager.class.getPackage())
				.addAsResource("test-persistence.xml", "META-INF/persistence.xml")
				.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
	}

	@Before
	public void setUp() {
		user = TestHelper.getNewUser();
		user.setReceivingEmail(false);
		um.createUser(user);

		event = TestHelper.getNewEvent();
		eventMgr.createEvent(event, user);
	}

	@Test
	public void testSendNotification() {
		cut.sendNotification(event.getDescription(), user, event);

		Notification notification = getNotification();
		User foundUser = em.find(User.class, user.getEmail());
		Notification foundNotification = em.find(Notification.class, notification.getNotificationId());

		assertNotNull(foundNotification);

		assertEquals(foundNotification, notification);
		assertEquals(foundNotification.getEvent(), notification.getEvent());
		assertEquals(foundNotification.getDescription(), notification.getDescription());

		assertEquals(notification.getOwner(), user);
		assertTrue(user.getNotifications().contains(notification));

		assertEquals(foundNotification.getOwner(), user);
		assertTrue(foundUser.getNotifications().contains(notification));

		String queryStr = "SELECT notificationId FROM NOTIFICATION WHERE owner = '" + user.getEmail() + "'";
		assertFalse(em.createNativeQuery(queryStr).getResultList().isEmpty());
	}

	@Test
	public void testRemoveNotification() {
		cut.sendNotification(event.getDescription(), user, event);
		Notification notification = getNotification();

		cut.removeNotification(notification);

		User foundUser = em.find(User.class, user.getEmail());
		Notification foundNotification = em.find(Notification.class, notification.getNotificationId());

		assertFalse(user.getNotifications().contains(notification));
		assertFalse(foundUser.getNotifications().contains(foundNotification));

		String queryStr = "SELECT notificationID FROM NOTIFICATION where notificationID = " + notification.getNotificationId();
		assertTrue(em.createNativeQuery(queryStr).getResultList().isEmpty());
	}

	private Notification getNotification() {
		Notification notification = null;
		for (Notification n : user.getNotifications()) {
			if (n.getEvent().equals(event)) {
				notification = n;
				break;
			}
		}
		return notification;
	}
}